<?php

namespace App\Core;

use App\Component\Jwt;
use App\Core\Exception\BaseException;
use App\Core\Exception\DefaultException;
use App\Lib\Mongodb\MongodbDriver;
use App\Util\CommonHelper;
use App\Util\UserIdentityHelper;
use EasySwoole\Component\Di;
use EasySwoole\Http\AbstractInterface\Controller;


class BaseController extends Controller{
    
    public function onException(\Throwable $throwable) : void{
        if (\EasySwoole\EasySwoole\Config::getInstance()->getConf('ENV') == 'produce'){
            $error = [
                'errormsg'     => $throwable->getMessage()
            ];
        }else{
            $error = [
                'errormsg'     => $throwable->getMessage(),
                'errorfile'    => $throwable->getFile(),
                'error_row'    => $throwable->getLine(),
                'error_trace'  => $throwable->getTrace(),
                'error_string' => $throwable->getTraceAsString()
            ];
        }
        
        $code = $throwable instanceof BaseException ? $throwable->getCode() : 600;
        
        //记录错误日志【除去DefaultException异常不记录】
        if(!$throwable instanceof BaseException){
            $ttArr = explode("\n", $throwable->getTraceAsString());
            $strString = implode('  <-  ', $ttArr);
            //\EasySwoole\EasySwoole\Logger::getInstance()->error($strString);
        }
        $this->writeJson($code, $error, $throwable->getMessage());
    }
    
    public function writeJsonByOutput(Output $output, $extraData = []){
        $output->pushData($extraData);
        $message = $output->msg;
        return $this->writeJson($output->getStatusCode(), $output->getData() ?: [], $message);
    }
    
    protected function getJson($key = null, $default = null){
        $jsonData = $this->json();

        if($key === null){
            return $jsonData ?: [];
        }
        
        return $jsonData[$key] ?? $default;
    }
    
    protected function json() : ?array{
        $result = parent::json();
        return CommonHelper::encode($result);
    }
    
    protected function writeJson($statusCode = 200, $result = null, $msg = null){
        if(!$this->response()->isEndResponse()){
            $data = array(
                "code"   => $statusCode,
                "result" => $result,
                "msg"    => $msg
            );
            $this->response()->write(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
            $this->response()->withHeader('Content-type', 'application/json;charset=utf-8');
            $this->response()->withStatus(200);
            return true;
        }else{
            return false;
        }
    }


    /**
     * 系统日志
     */
    protected function sysLog($module, $jwtToken = null)
    {
        $data = [];

        //请求地址
        $data['url_path'] = $this->request()->getUri()->getPath();
        //新token
        $data['jwtToken'] = $jwtToken;

        //请求方式
        $data['method'] = $this->request()->getMethod();

        //请求参数
        if ($data['method'] == 'GET') {
            $params = $this->request()->getQueryParams();
            //return true; //get方法暂时不存储
        } else {
            //除get请求外，接收json格式
            $params = $this->getJson();

            if (isset($params['password'])) {
                $params['password'] = '****';
            }
            /**登录接口*/
            if ($data['url_path'] == '/api/member/login') {
                if (empty($jwtToken)) {
                    throw new DefaultException('jwt-token不存在');
                }
                /** @var Jwt $jwt */
                $jwt      = Di::getInstance()->get('jwt');
                $parseJwt = $jwt->validateToken($jwtToken);
                $parseData     = $parseJwt->data;
                if ($parseData['username'] != $params['username']) {
                    throw new DefaultException('发生错误,请重新登录!');
                }
            }
        }
        //参数转json字符串
        $data['params'] = json_encode($params,JSON_UNESCAPED_UNICODE);
//        $data['params'] = $params;

        //请求ip
//        $server = $this->request()->getSwooleRequest()->server;
//        $data['remote_addr'] = $server['remote_addr'];
        $clientIP = $this->request()->getHeaders()['x-real-ip'] ?? $this->request()->getHeaders()['x-forwarded-for'] ?? $this->request()->getSwooleRequest()->server['remote_addr'];
        $data['remote_addr'] = is_array($clientIP) ? $clientIP[0] : $clientIP;

        //操作人
        $data['username'] = UserIdentityHelper::getUsername();

        //操作人id
        $data['uid'] = UserIdentityHelper::getId();

        //操作时间
        $data['optime'] = time();

        //token
        if ($this->request()->hasHeader('jwt-token')){
            $data['token'] = $this->request()->getHeader('jwt-token');
        }

        /** @var MongodbDriver $mongo */
        $mongo = Di::getInstance()->get("MONGODB");
        if (!$mongo instanceof MongodbDriver) {
            return ;
        }
        $mongo = $mongo->getDb();
        //集合
        $collection = $module . '_log-' . date("Ym");

        //写入操作数据
        $mongo->$collection->insertOne($data);
    }


}
